package com.binance.zkconfig.app.archainus;

import com.netflix.config.AggregatedConfiguration;
import com.netflix.config.ConcurrentCompositeConfiguration;
import com.netflix.config.ConfigurationManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.configuration.AbstractConfiguration;
import org.apache.commons.configuration.EnvironmentConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;

import javax.annotation.PostConstruct;

/**
 * Created by Fei.Huang on 2018/8/28.
 */
@Slf4j
public class ArchaiusConfig {

    @Autowired
    private ConfigurableEnvironment configurableEnvironment;

    @PostConstruct
    public void start() {
        ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();

        // Load SpringConfigurableEnvironmentConfiguration
        ConfigurableEnvConfig configurableEnvConfig = new ConfigurableEnvConfig(this.configurableEnvironment);
        config.addConfiguration(configurableEnvConfig, ConfigurableEnvConfig.class.getSimpleName());

        // Load System.getProperties()
        SystemConfiguration systemConfiguration = new SystemConfiguration();
        config.addConfiguration(systemConfiguration, SystemConfiguration.class.getSimpleName());

        // Load System.getenv()
        EnvironmentConfiguration environmentConfiguration = new EnvironmentConfiguration();
        config.addConfiguration(environmentConfiguration, EnvironmentConfiguration.class.getSimpleName());

        addArchaiusConfig(config);
    }

    private void addArchaiusConfig(ConcurrentCompositeConfiguration config) {
        if (!ConfigurationManager.isConfigurationInstalled()) {
            ConfigurationManager.install(config);
            return;
        }
        AbstractConfiguration installedConfiguration = ConfigurationManager.getConfigInstance();
        if (installedConfiguration instanceof ConcurrentCompositeConfiguration) {
            ConcurrentCompositeConfiguration configInstance = (ConcurrentCompositeConfiguration) installedConfiguration;
            configInstance.addConfiguration(config);
        } else {
            installedConfiguration.append(config);
            if (!(installedConfiguration instanceof AggregatedConfiguration)) {
                log.warn("ZkConfig appending a configuration to an existing non-aggregated installedConfiguration will have no effect");
            }
        }
    }
}
